#!/usr/bin/env python 
# -*- coding: utf-8 -*-  

import datetime
from static import make_image_array
from point import Point

class Cleaner:
    def __init__(self):
        self.arr = []
        self.arr2 = []
        self.point_array = []
        
    def delete_salt_and_pepper(self, arr, w, h):
        c = 0
        for j in xrange(h):
            for i in xrange(w):
                if not arr[i][j] in (arr[i][j-1], arr[i-1][j], arr[i+1][j], arr[i][j+1]):
                    arr[i][j] = arr[i-1][j]
                    c += 1
        print "%d points cleared" % c
        return arr
    
    #Метод Зонга-Суня. Удаление точек с северо-восточной границы
    def may_delete_SE(self, i, j):
        kontur = [self.arr[i-1][j-1],self.arr[i][j-1],self.arr[i+1][j-1],self.arr[i+1][j],
                  self.arr[i+1][j+1],self.arr[i][j+1],self.arr[i-1][j+1],self.arr[i-1][j],self.arr[i-1][j-1]]
        conditionA = sum(kontur) - self.arr[i-1][j-1]
        conditionB = self.num01transitions(kontur)
        conditionC = kontur[1]*kontur[3]*kontur[5]
        conditionD = kontur[3]*kontur[5]*kontur[7]
        return (conditionA >= 2 and conditionA <= 6 and conditionB == 1 and conditionC == 0 and conditionD == 0)
    
    #Метод Зонга-Суня. Удаление точек с юго-западной границы
    def may_delete_NW(self, i, j):
        kontur = [self.arr[i-1][j-1],self.arr[i][j-1],self.arr[i+1][j-1],self.arr[i+1][j],
                  self.arr[i+1][j+1],self.arr[i][j+1],self.arr[i-1][j+1],self.arr[i-1][j],self.arr[i-1][j-1]]
        conditionA = sum(kontur) - self.arr[i-1][j-1]
        conditionB = self.num01transitions(kontur)
        conditionC = kontur[1]*kontur[3]*kontur[7]
        conditionD = kontur[1]*kontur[5]*kontur[7]
        return (conditionA >= 2 and conditionA <= 6 and conditionB == 1 and conditionC == 0 and conditionD == 0)
    
    #Метод Зонга-Суня. подсчет числа переходов типа "01" в контуре точки
    def num01transitions(self, kontur):
        zero_num=0
        for a in xrange (len(kontur)-1):
            if (kontur[a+1] - kontur[a]) == 1:
                zero_num += 1
        return zero_num
    
    def may_delete_special_combinations(self, i, j):
        kontur = [self.arr[i-1][j-1],self.arr[i][j-1],self.arr[i+1][j-1],self.arr[i+1][j],
                  self.arr[i+1][j+1],self.arr[i][j+1],self.arr[i-1][j+1],self.arr[i-1][j]]
        delete_list = [[1,0,0,0,0,1,0,1],[0,1,0,1,1,0,0,0],[0,0,1,1,0,1,0,0],[0,1,0,0,0,0,1,1],[0,0,0,1,0,1,1,0],
                       [0,0,0,0,1,1,0,1],[0,1,1,0,0,0,0,1],[1,1,0,1,0,0,0,0],[0,1,0,0,0,0,0,1],[0,1,0,1,0,0,0,0],
                       [0,0,0,1,0,1,0,0],[0,0,0,0,0,1,0,1],[0,0,0,0,0,0,0,0]]
        return kontur in delete_list
    
    def may_delete_special_point(self, i, j):
        kontur = [self.arr[i-1][j-1],self.arr[i][j-1],self.arr[i+1][j-1],self.arr[i+1][j],
                  self.arr[i+1][j+1],self.arr[i][j+1],self.arr[i-1][j+1],self.arr[i-1][j]]
        return sum(kontur) > 2
    
    #получение массива точек
    def make_point_array(self):
        w,h = len(self.arr),len(self.arr[0])
        for j in xrange(1,h-2):
            for i in xrange(1,w-2):
                if self.arr[i][j] == 1:
                    point = Point(i, j, 0)
                    self.point_array.append(point)
    
    def thin_image(self, image):
        self.arr, w, h = make_image_array(image)
        self.arr2, w, h = make_image_array(image)
        print "delete salt and pepper"
        self.arr = self.delete_salt_and_pepper(self.arr, w, h)
        self.arr2 = self.delete_salt_and_pepper(self.arr2, w, h)
        self.make_point_array()
        self.zong_sun_thinning()
        for point in self.point_array:
            self.arr2[point.get_x()][point.get_y()] = self.arr[point.get_x()][point.get_y()]
            if self.arr[point.get_x()][point.get_y()] != 0 and self.may_delete_special_point(point.get_x(), point.get_y()):
                self.arr2[point.get_x()][point.get_y()] = 0
        return self.arr2
    
    def zong_sun_thinning(self):
        ops = 100
        while ops > 0:
            ops = 0
            for point in self.point_array:
                if not point.get_checked() and self.may_delete_SE(point.get_x(), point.get_y()):
                    self.arr2[point.get_x()][point.get_y()] = 0
                    ops += 1
                    point.set_checked(True)
            for point in self.point_array:
                if self.arr2[point.get_x()][point.get_y()] == 0 and self.arr[point.get_x()][point.get_y()] != 0:
                    self.arr[point.get_x()][point.get_y()] = 0
            for point in self.point_array:
                if not point.get_checked() and self.may_delete_NW(point.get_x(), point.get_y()):
                    self.arr2[point.get_x()][point.get_y()] = 0
                    ops += 1
                    point.set_checked(True)
            for point in self.point_array:
                if self.arr2[point.get_x()][point.get_y()] == 0 and self.arr[point.get_x()][point.get_y()] != 0:
                    self.arr[point.get_x()][point.get_y()] = 0
            print "%d pixels deleted" % (ops)
        for point in self.point_array:
            if self.arr[point.get_x()][point.get_y()] != 0 and self.may_delete_special_combinations(point.get_x(), point.get_y()):
                self.arr[point.get_x()][point.get_y()] = 0